package com.m4f.cityclient.oauth.consumer;

import java.util.logging.Level;
import java.util.logging.Logger;

import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.util.SerializationUtils;
import org.springframework.security.oauth2.consumer.OAuth2ProtectedResourceDetails;
import org.springframework.security.oauth2.consumer.token.OAuth2ClientTokenServices;

import com.google.appengine.api.datastore.Blob;
import com.m4f.cityclient.common.model.M4FOAuthUser;
import com.m4f.cityclient.common.service.ifc.M4FOAuthUserService;
import com.m4f.gaeweb.web.utils.StackTraceUtil;



public class DataStoreOAuth2ClientTokenServices implements OAuth2ClientTokenServices {
	private static final Logger LOGGER = Logger.getLogger(DataStoreOAuth2ClientTokenServices.class.getName());
	
	private M4FOAuthUserService userService;

	public DataStoreOAuth2ClientTokenServices(M4FOAuthUserService userService) {
		this.userService = userService;	
	}

	@Override
	public OAuth2AccessToken getToken(Authentication auth, OAuth2ProtectedResourceDetails resource) {
		OAuth2AccessToken accessToken = null;
		
		try {
			if (auth != null && auth.isAuthenticated() && auth.getPrincipal() instanceof M4FOAuthUser) {
				M4FOAuthUser user = (M4FOAuthUser) auth.getPrincipal();
				if(user != null && user.getOauthAccessTokens() != null && user.getOauthAccessTokens().get(resource.getId()) != null) {
					accessToken = SerializationUtils.deserialize(user.getOauthAccessTokens().get(resource.getId()).getBytes());
				}
		    }
		} catch(Exception e) {
			LOGGER.log(Level.FINEST, StackTraceUtil.getStackTrace(e));
		}

	    return accessToken;
	}

	@Override
	public void removeToken(Authentication auth, OAuth2ProtectedResourceDetails resource) {
		if (auth != null && auth.isAuthenticated() && auth.getPrincipal() instanceof M4FOAuthUser) {
			M4FOAuthUser user = (M4FOAuthUser) auth.getPrincipal();
			user.getOauthAccessTokens().put(resource.getId(), null);
			
			try {
				this.userService.save(user);
			} catch(Exception e) { 
				LOGGER.log(Level.FINEST, StackTraceUtil.getStackTrace(e));
			}
	    }
		
	}

	@Override
	public void storeToken(Authentication auth,	OAuth2ProtectedResourceDetails resource, OAuth2AccessToken token) {
		if (auth != null && auth.isAuthenticated() && auth.getPrincipal() instanceof M4FOAuthUser) {
			M4FOAuthUser user = (M4FOAuthUser) auth.getPrincipal();
			user.getOauthAccessTokens().put(resource.getId(), new Blob(SerializationUtils.serialize(token)));
			try {
				this.userService.save(user);
			} catch(Exception e) { 
				LOGGER.log(Level.FINEST, StackTraceUtil.getStackTrace(e));
			}
	    }
	}

	@Override
	public void updateToken(Authentication auth, OAuth2ProtectedResourceDetails resource, OAuth2AccessToken oldToken,
			OAuth2AccessToken newToken) {
		storeToken(auth, resource, newToken);		
	}
}
